﻿using SelfMadeMillionaire.Core;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Enums;
using SelfMadeMillionaire.Core.Services;
using SelfMadeMillionaire.Web.Infrastructure.Controllers;
using SelfMadeMillionaire.Web.Infrastructure.Formatters;
using SelfMadeMillionaire.Web.Infrastructure.ViewModels.Publications;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using PagedList;
using SelfMadeMillionaire.Core.Specifications.Publications;

namespace SelfMadeMillionaire.Web.Infrastructure.Controllers.Admin
{
	public class PublicationsController : AdminController
	{
		IPublicationService _publicationService;
        IPublicationProductService _publicationProductService;

		public PublicationsController(IPublicationService publicationService, IPublicationProductService publicationProductService)
		{
			_publicationService = publicationService;
            _publicationProductService = publicationProductService;
		}

        class PublicationsFilterSave
        {
            public DateTime? StartDate;
            public DateTime? EndDate;
            public ProductType? SelectedProduct;
            public string Title;
            public int? Page;
            public int? IsHP;
            public int? IsEd;
            public byte? MinAccessLevel;
            public string Sort;
        }

        public ActionResult Index(DateTime? startDate, DateTime? endDate, ProductType? selectedProduct, string title, int? page, int? isHP, int? isEd, byte? minAccessLevel, string sort)
		{
            if (Session["UsePublicationsFilter"] != null && Session["PublicationsFilter"] != null)
            {
                Session["UsePublicationsFilter"] = null;
                var filter = Session["PublicationsFilter"] as PublicationsFilterSave;

                startDate = filter.StartDate;
                endDate = filter.EndDate;
                selectedProduct = filter.SelectedProduct;
                title = filter.Title;
                page = filter.Page;
                isHP = filter.IsHP;
                isEd = filter.IsEd;
                minAccessLevel = filter.MinAccessLevel;
                sort = filter.Sort;
            }
            else
            {
                Session["PublicationsFilter"] = new PublicationsFilterSave()
                {
                    StartDate = startDate,
                    EndDate = endDate,
                    SelectedProduct = selectedProduct,
                    Title = title,
                    Page = page,
                    IsHP = isHP,
                    IsEd = isEd,
                    MinAccessLevel = minAccessLevel,
                    Sort = sort
                };
            }


			int pageIndex = page ?? 1;
			int pageSize = 10;

            bool bIsShowOnHomePage = (isHP.HasValue && (isHP.Value == 1));
            bool bIsEducation = (isEd.HasValue && (isEd.Value == 1));

			startDate = startDate ?? DateTime.Today.AddMonths(-1);
			endDate = endDate ?? DateTime.Today;

			var model = new PublicationListViewModel
			{
                IsSendLinkVisible = IsUsIP(),
				StartDate = startDate,
				EndDate = endDate,
				ProductTypes = GetProductTypes(selectedProduct),
                AccessLevels = GetAccessLevelsFilter(minAccessLevel.HasValue ? minAccessLevel.ToString() : null),
				Title = title,
                IsEducation = bIsEducation,
                IsShowOnHomePage = bIsShowOnHomePage,
                SortOrder = sort
			};

            IEnumerable<Publication> list = _publicationService.GetList(new PublicationsListSpecification(startDate, endDate, selectedProduct, title, true, null, bIsShowOnHomePage, bIsEducation, (SubscriptionType?)minAccessLevel));
            if (!string.IsNullOrEmpty(sort))
            {
                string[] sortArr = sort.Split(',');
                if (sortArr[1] == "0")
                {

                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderBy(i => i.Date);
                            break;
                        case "1":
                            list = list.OrderBy(i => ProductTypeFormatter.GetProductTypeName((ProductType)Enum.Parse(typeof(ProductType), i.ProductType.ToString())));
                            break;
                        case "2":
                            list = list.OrderBy(i => i.Title);
                            break;
                        case "3":
                            list = list.OrderBy(i => i.IsShowOnHomePage);
                            break;
                        case "4":
                            list = list.OrderBy(i => i.EmailMessage == null ? DateTime.MinValue : i.EmailMessage.DateSent);
                            break;
                    }

                }
                else
                {
                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderByDescending(i => i.Date);
                            break;
                        case "1":
                            list = list.OrderByDescending(i => ProductTypeFormatter.GetProductTypeName((ProductType)Enum.Parse(typeof(ProductType), i.ProductType.ToString())));
                            break;
                        case "2":
                            list = list.OrderByDescending(i => i.Title);
                            break;
                        case "3":
                            list = list.OrderByDescending(i => i.IsShowOnHomePage);
                            break;
                        case "4":
                            list = list.OrderByDescending(i => i.EmailMessage == null ? DateTime.MinValue : i.EmailMessage.DateSent);
                            break;
                    }
                }
            }
            model.Publications = list.ToPagedList(pageIndex, pageSize);

			if (Request.IsAjaxRequest())
				return PartialView("PublicationsList", model);

			return View(model);
		}
		[HttpGet]
		public ActionResult Add()
		{
			var model = new PublicationEditViewModel
			{
				Publication = new Publication() { Date = DateTime.Today },
				ProductTypes = GetProductTypes(),
				AccessLevels = GetAccessLevels(null),
                SelectedProducts = new List<int>()
			};

            Session["UsePublicationsFilter"] = true;
			return View(model);
		}

		[ValidateInput(false)]
		[HttpPost]
		public ActionResult Add(PublicationEditViewModel model)
		{
			if (ModelState.IsValid)
			{
				if (model.PdfFile != null)
				{
					model.PdfFile.SaveAs(FileLink.GetSaveFilePath(model.PdfFile.FileName));
					model.Publication.PdfFileName = model.PdfFile.FileName;
				}

                //model.Publication.MinAccessLevel = (byte)SubscriptionType.Platinum;
                model.Publication.MinAccessLevelOriginal = model.Publication.MinAccessLevel;

                model.Publication.Products = new List<PublicationProduct>();
                if (model.SelectedProducts != null)
                {
                    model.SelectedProducts.ForEach(x => model.Publication.Products.Add(new PublicationProduct() { ProductType = (byte)x }));
                }

				_publicationService.Add(model.Publication);
				return RedirectToAction("Index");
			}

			model.ProductTypes = GetProductTypes((ProductType)model.Publication.ProductType);
			model.AccessLevels = GetAccessLevels(model.MinAccessLevel);

			return View(model);
		}


		[HttpGet]
        public ActionResult Edit(int id, DateTime? startDate, DateTime? endDate, ProductType? selectedProduct, string title, int? page, int? isHP, int? isEd, byte? minAccessLevel, string sort)
		{
			var publication = _publicationService.Get(id);
            publication.MinAccessLevel = publication.MinAccessLevelOriginal;

			var model = new PublicationEditViewModel
			{
				Publication = publication,
				ProductTypes = GetProductTypes((ProductType)publication.ProductType),
				AccessLevels = GetAccessLevels(publication.MinAccessLevel),

                SelectedProduct = selectedProduct,
                StartDate = startDate,
                EndDate = endDate,
                Title = title,
                MinAccessLevel = publication.MinAccessLevelOriginal,
                SortOrder = sort,
                SelectedProducts = publication.Products.Select(x => (int)x.ProductType).ToList()
			};

            Session["UsePublicationsFilter"] = true;
			return View(model);
		}

		[ValidateInput(false)]
		[HttpPost]
		public ActionResult Edit(PublicationEditViewModel model)
		{
			if (ModelState.IsValid)
			{
				if (model.PdfFile != null)
				{
					model.PdfFile.SaveAs(FileLink.GetSaveFilePath(model.PdfFile.FileName));
					model.Publication.PdfFileName = model.PdfFile.FileName;
				}

                model.Publication.MinAccessLevelOriginal = model.Publication.MinAccessLevel;
                //model.Publication.MinAccessLevel = (byte)SubscriptionType.Platinum;

                model.Publication.Products = _publicationService.Get(model.Publication.ID).Products;
                model.Publication.Products.ToList().ForEach(x => _publicationProductService.Remove(x.ID));
                if (model.SelectedProducts != null)
                {
                    model.SelectedProducts.ForEach(x => model.Publication.Products.Add(new PublicationProduct() { ProductType = (byte)x }));
                }

				_publicationService.Update(model.Publication);

				string startDate = model.StartDate.HasValue ? model.StartDate.Value.ToString(Constants.DATE_FORMAT) : null;
				string endDate = model.EndDate.HasValue ? model.EndDate.Value.ToString(Constants.DATE_FORMAT) : null;

                return RedirectToAction("Index", new { startDate = startDate, endDate = endDate, selectedProduct = model.SelectedProduct, title = model.Title, minAccessLevel = model.MinAccessLevel, sort = model.SortOrder });
			}

			model.ProductTypes = GetProductTypes((ProductType)model.Publication.ProductType);
			model.AccessLevels = GetAccessLevels(model.MinAccessLevel);

			return View(model);
		}

		[HttpPost]
        public void Delete(int id)
		{
			_publicationService.Remove(id);
		}

        [HttpPost]
        public void Send(int id)
		{
			string emailTemplate = System.IO.File.ReadAllText(Server.MapPath("~/EmailTemplates/Subscription.html"));
            _publicationService.Send(id, emailTemplate);
		}

        [HttpPost]
        public void Hide(int id)
        {
            _publicationService.Hide(id);
        }

        [HttpPost]
        public void Show(int id)
        {
            _publicationService.Show(id);
        }
	}
}
